Skip to content

Python(feat): resume incomplete test report upload - #745

Open
alexluck-sift wants to merge 5 commits into
mainfrom
al/python/feat/resume-incomplete-test-report-upload
Open

Python(feat): resume incomplete test report upload#745
alexluck-sift wants to merge 5 commits into
mainfrom
al/python/feat/resume-incomplete-test-report-upload

Conversation

@alexluck-sift

@alexluck-sift alexluck-sift commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

import-test-result-log <log> now finishes an interrupted upload instead of creating a second report.

Every upload records what reached the server in a tracking sidecar beside the log (<log>.jsonl.tracking). A re-run reuses the report the earlier attempt created and sends only the missing entries; a fully uploaded log is a no-op. Resuming needs that report to still exist, so if it was deleted or the sidecar came from another environment the command fails and points at --new-report.

--new-report, and import_log_file(..., new_report=True), abandons the partial upload and creates a new report. The old sidecar moves to .tracking.bak so the abandoned report's ID stays recoverable.

import-test-result-log is now two modes, and the help text, docstrings, and guide all name the same two:

Mode How to get it Who it is for
New upload default, nothing uploaded yet First upload of a log
Resume default, sidecar records an interrupted upload Anyone re-running after an interruption

The third mode is gone from the public command. --incremental followed a log while the run writing it was still going, which only the plugin's background worker has a reason to do, and it ticked until stdin closed rather than stopping at the end of the log, so it was never a way to finish an interrupted upload and appeared to hang when run by hand. That mode now runs as an internal worker module the plugin spawns for itself, reachable by no flag. Anything passing --incremental by hand should drop it, since the default path resumes.

The two entry points share their connection arguments, client construction, and failure hint through one internal module rather than a copy each, and the worker no longer imports the report-context chain at startup, which was roughly 190 ms of pandas it needs only on the failure path.

16 new tests cover batch progress recording, resume through both paths, partially created batched measurement lines, the completed no-op, --new-report, the error paths, and the worker's follow mode, where an idle tick stays silent and never marks a growing log complete. 214 tests pass across the replay, session-artifact, report-context, and plugin suites. Also checked end to end against a plugin-produced offline log: an upload interrupted partway resumes to the same 63 entities as a clean run, with no duplicate report.

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Python docs preview: https://sift-stack.github.io/sift/python/pr-745/

Deployed from 4e70010. The link may take up to a minute to become live as GitHub Pages propagates.

@alexluck-sift
alexluck-sift marked this pull request as ready for review August 21, 2026 18:46
@ian-sift

Copy link
Copy Markdown
Contributor

claude review:
The docstring says the live worker leaves resuming False because EOF of a growing file isn’t end-of-run. The code does the opposite: after the first successful worker tick, last_uploaded_line > 0 forces resuming=True, so every subsequent tick (including idle ones) sets complete=True.

Failure mode:

  1. Plugin worker uploads some lines under --incremental
  2. Worker is killed mid-suite; sidecar has complete=True and a partial id_map
  3. User runs the recovery hint: import-test-result-log
  4. Default path sees tracking.complete → returns empty ReplayResult as a no-op
  5. Remaining lines never upload

The PR description claims a test that “an idle tick … never marks a growing log complete.” That test is not in the tree — and the current code would fail it.

This used to be only a “skip CreateTestReport missing” guard. The PR overloaded that flag to also mean “log is final.” Split them

@alexluck-sift
alexluck-sift force-pushed the al/python/feat/resume-incomplete-test-report-upload branch from 2af8c73 to fc82476 Compare August 21, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants